import { languages, currentLanguage } from '@/shared'
import { Base64 } from 'js-base64'
import { ref, type Ref } from 'vue'
import CryptoJS from 'crypto-js'

// 语音合成相关
export const useVoice = () => {
  // 语音合成 websocket 实例
  let ttsWS: WebSocket
  // 语音播放器实例
  const audioPlayer: Ref<any> = ref()

  // 初始化语音播放器实例
  function initAudioPlayer() {
    const AudioPlayer = (window as any).AudioPlayer
    audioPlayer.value = new AudioPlayer('/tts')
  }

  // 连接语音合成 websocket
  function connectVoiceWebSocketUrl(text: string) {
    const websocketUrl = getVoiceWebSocketUrl()
    ttsWS = new WebSocket(websocketUrl)
    ttsWS.onopen = () => {
      audioPlayer.value.start({
        autoPlay: true,
        sampleRate: 16000,
        resumePlayDuration: 1000
      })
      const params = {
        common: {
          app_id: (window as any).APP_ID
        },
        business: {
          aue: 'raw',
          auf: 'audio/L16;rate=16000',
          vcn: languages[currentLanguage.value].vcn,
          speed: languages[currentLanguage.value].speed,
          volume: 100,
          pitch: 50,
          bgs: 0,
          tte: 'UTF8'
        },
        data: {
          status: 2,
          text: encodeText(text)
        }
      }
      ttsWS.send(JSON.stringify(params))
    }
    ttsWS.onmessage = (e) => {
      const jsonData = JSON.parse(e.data)
      audioPlayer.value.postMessage({
        type: 'base64',
        data: jsonData.data.audio,
        isLastData: jsonData.data.status === 2
      })
      if (jsonData.code === 0 && jsonData.data.status === 2) {
        ttsWS.close()
      }
    }
  }

  // 参考官方示例
  function encodeText(text: string) {
    return Base64.encode(text)
  }

  // 生成语音合成 websocket 接口
  function getVoiceWebSocketUrl() {
    let url = 'wss://tts-api.xfyun.cn/v2/tts'
    const host = location.host
    const date = new Date().toUTCString()
    const algorithm = 'hmac-sha256'
    const headers = 'host date request-line'
    const signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/tts HTTP/1.1`
    const signatureSha = CryptoJS.HmacSHA256(signatureOrigin, (window as any).API_SECRET)
    const signature = CryptoJS.enc.Base64.stringify(signatureSha)
    const authorizationOrigin = `api_key="${
      (window as any).API_KEY
    }", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
    const authorization = btoa(authorizationOrigin)
    url = `${url}?authorization=${authorization}&date=${date}&host=${host}`
    return url
  }

  return {
    connectVoiceWebSocketUrl,
    initAudioPlayer,
    audioPlayer
  }
}
